package com.hqumath.androidnative.tools;

import android.app.Instrumentation;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.hqumath.androidnative.app.AppExecutors;
import com.hqumath.androidnative.app.Constant;
import com.hqumath.androidnative.utils.LogUtil;
import com.jeremyliao.liveeventbus.LiveEventBus;

/**
 * 输入设备工具类
 */
public class GameDevice {
    private final static String TAG = "GameDevice";
    public final static String ControllerIdG29 = "046d:c24f";//Logitech G29 PS3模式。PS4模式部分按键无反应
    public final static String ControllerIdT150 = "044f:b65d";//Thrustmaster T150/T300 PS3模式。PS4模式部分按键无反应。PS3模式踏板变为开关量

    public static String curControllerId = "";//当前输入设备id

    //方向 速度 挡位
    private static float turn = 0f;//转向∈[-1,1]
    private static float clutch = 0f;//离合∈[0,1]
    private static float gas = 0f;//油门∈[0,1]
    private static float brake = 0f;//刹车∈[0,1]

    private static float lastTurn, lastGas;//上一个值，用于判断方向盘转动事件、油门踏板踩下事件

    //恢复默认参数
    public static void reset() {
        turn = 0f;
        clutch = 0f;
        gas = 0f;
        brake = 0f;
    }

    public static float getTurn() {
        return turn;
    }

    public static void setTurn(float turn) {
        GameDevice.turn = turn;
    }

    public static float getClutch() {
        return clutch;
    }

    public static void setClutch(float clutch) {
        GameDevice.clutch = clutch;
    }

    public static float getGas() {
        return gas;
    }

    public static void setGas(float gas) {
        GameDevice.gas = gas;
    }

    public static float getBrake() {
        return brake;
    }

    public static void setBrake(float brake) {
        GameDevice.brake = brake;
    }

    /**
     * 模拟遥控器点击事件
     *
     * @param keyCode
     */
    public static void clickKey(int keyCode) {
        AppExecutors.getInstance().workThread().execute(() -> {
            Instrumentation mInstrumentation = new Instrumentation();
            KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
            keyEventDown.setSource(InputDevice.SOURCE_DPAD);//遥控器
            mInstrumentation.sendKeySync(keyEventDown);
            KeyEvent keyEventUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
            keyEventUp.setSource(InputDevice.SOURCE_DPAD);
            mInstrumentation.sendKeySync(keyEventUp);
        });
    }

    /**
     * 获取设备id
     *
     * @param dev
     * @return
     */
    public static String getInputDeviceId(InputDevice dev) {
        if (dev == null)
            return ":";
        StringBuilder mVendorId = new StringBuilder(Integer.toHexString(dev.getVendorId()));//厂商
        StringBuilder mProductId = new StringBuilder(Integer.toHexString(dev.getProductId()));//产品系列
        while (mVendorId.length() < 4) mVendorId.insert(0, "0");//补全四个字符，前面加0
        while (mProductId.length() < 4) mProductId.insert(0, "0");
        return mVendorId + ":" + mProductId;
    }

    /**
     * 拦截方向盘事件
     *
     * @param keyCode
     * @param event
     * @return
     */
    public static boolean onKeyDown(int keyCode, KeyEvent event) {
        LogUtil.d(TAG, "onKeyDown, keyCode=" + keyCode);
        InputDevice device = event.getDevice();
        if (device != null && device.getName().contains("Wheel")) {
            return true;
        }
        return false;
    }

    /**
     * 拦截方向盘事件
     *
     * @param keyCode
     * @param event
     * @return
     */
    public static boolean onKeyUp(int keyCode, KeyEvent event) {
        LogUtil.d(TAG, "onKeyUp, keyCode=" + keyCode);
        InputDevice device = event.getDevice();
        if (device != null && device.getName().contains("Wheel")) {
            return true;
        }
        return false;
    }

    /**
     * 拦截方向盘事件
     *
     * @param event
     * @return
     */
    public static boolean onGenericMotionEvent(MotionEvent event) {
        float x = event.getAxisValue(MotionEvent.AXIS_X);//左摇杆 左右∈[-1.0,1.0]
        float y = event.getAxisValue(MotionEvent.AXIS_Y);//左摇杆 上下∈[-1.0,1.0] 速度
        float z = event.getAxisValue(MotionEvent.AXIS_Z);//右摇杆 左右∈[-1.0,1.0] 方向
        //float rz = event.getAxisValue(MotionEvent.AXIS_RZ);//右摇杆 上下∈[-1.0,1.0]
        float hatX = event.getAxisValue(MotionEvent.AXIS_HAT_X);//方向键 左-1.0 中0.0 右1.0
        float hatY = event.getAxisValue(MotionEvent.AXIS_HAT_Y);//方向键 上-1.0 中0.0 下1.0
        //float l = event.getAxisValue(MotionEvent.AXIS_LTRIGGER);//左扳机
        //float r = event.getAxisValue(MotionEvent.AXIS_RTRIGGER);//右扳机
        LogUtil.d(TAG, "onGenericMotionEvent");
        //方向键
        if (hatX == -1.0) {
            GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_LEFT);
        } else if (hatX == 1.0) {
            GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_RIGHT);
        } else if (hatY == -1.0) {
            GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_UP);
        } else if (hatY == 1.0) {
            GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_DOWN);
        }

        InputDevice device = event.getDevice();
        if (device != null && device.getName().contains("Wheel")) {
            return true;
        }
        return false;
    }

    //低频处理方向盘数据,发送方向盘转动事件+油门踏板踩下事件
    public static void handleWheelMessage() {
        float turn = getTurn();
        float gas = getGas();
        if (Math.abs(turn - lastTurn) > 0.2) {//差值足够大
            lastTurn = turn;
            LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_DIRECTION);
        } else if (Math.abs(gas - lastGas) > 0.2) {//差值足够大
            lastGas = gas;
            LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_SPEED);
        }
    }
}
